﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using ScrollingBackgroundSpace;

namespace MiaProject
{
    class Menu
    {
        List<MenuItem> itemList;
        List<MenuItem> menuList;
        List<MenuItem> controlsList;
        List<MenuItem> pauseList;
        List<MenuItem> deadList;
        List<MenuItem> levelChangeList;
        List<MenuItem> levelChange2DList;
        List<MenuItem> levelLose2DList;
        List<MenuItem> pauseList2D;
        List<MenuItem> controlsList2D;
        
        
        SpriteFont font;
        public Boolean active;
        private int currentItem;
        private Texture2D background;
        private Texture2D star;

        private Boolean keyPressUp;
        private Boolean keyPressDown;
        private Boolean keyPressEnter;
        public Boolean optionSelected;//true para enter pressionado em alguma opcao
        
        public Boolean menuScreen;
        public Boolean loadingScreen;
        public Boolean controlScreen;
        
        public int type;
        public int owner;
        public Boolean execAction;

        private ScrollingBackground myBackground1;
        private ScrollingBackground myBackground2;
        
    
        public const int TYPE_MENU_START = 1;
        public const int TYPE_CHANGE_LEVEL_3D = 2;
        public const int TYPE_CHANGE_LEVEL_2D = 3;
        public const int TYPE_PAUSE = 4;
        public const int TYPE_DEAD  = 5;
        public const int TYPE_LOSE_LEVEL_2D = 6;
        public const int TYPE_PAUSE_2D = 7;

        
        public const int NEWGAME        = 1;
        public const int CONTROLS       = 2;
        public const int EXIT           = 3;
        public const int BACK           = 4;
        public const int LEFT           = 5;
        public const int RIGHT          = 6;
        public const int SHOT           = 7;
        public const int REDUCE         = 8;
        public const int SCORE          = 9;
        public const int ENEMY_KILL     = 10;
        public const int POWER_UP       = 11;
        public const int CONTINUE_3D    = 12;
        public const int RESUME         = 13;
        public const int CONTINUE_2D    = 14;
        public const int RESTART_LEVEL_3D = 15;
        public const int RESTART_LEVEL_2D = 16;
        public const int RESUME_2D = 17;
        public const int CONTROLS_2D = 18;
        public const int BACK_2D = 19;
        public const int CAMERA = 20;
        
        

        public Menu()
        {
            execAction = false;
            menuList = new List<MenuItem>();
            menuList.Add(new MenuItem(NEWGAME, "New Game", true));
            menuList.Add(new MenuItem(CONTROLS, "Controls", true));
            menuList.Add(new MenuItem(CAMERA, "Change View", true));
            menuList.Add(new MenuItem(EXIT, "Exit", true));

            pauseList = new List<MenuItem>();
            pauseList.Add(new MenuItem(RESUME, "Resume", true));
            pauseList.Add(new MenuItem(CONTROLS, "Controls", true));
            pauseList.Add(new MenuItem(CAMERA, "Change View", true));
            pauseList.Add(new MenuItem(EXIT, "Exit", true));

            deadList = new List<MenuItem>();
            deadList.Add(new MenuItem(SCORE, "YOU LOSE!!!", false));
            deadList.Add(new MenuItem(RESTART_LEVEL_3D, "Continue", true));
            deadList.Add(new MenuItem(EXIT, "Exit", true));


            controlsList = new List<MenuItem>();
            controlsList.Add(new MenuItem(LEFT,   "Move Left: Left"             ,false));
            controlsList.Add(new MenuItem(RIGHT,  "Move Right: Right"           ,false));
            controlsList.Add(new MenuItem(SHOT,   "Shot: S"                     ,false));
            controlsList.Add(new MenuItem(REDUCE, "Reduce velocity: Space"      ,false));
            controlsList.Add(new MenuItem(BACK,   "Back"                        ,true));
            controlsList.Add(new MenuItem(EXIT,   "Exit"                        ,true));
            
            levelChangeList = new List<MenuItem>();
            levelChangeList.Add(new MenuItem(SCORE,       "Score: "             ,false));
            levelChangeList.Add(new MenuItem(ENEMY_KILL,  "Enemy Kill"          ,false));
            levelChangeList.Add(new MenuItem(POWER_UP,    "Power Ups: "         ,false));
            levelChangeList.Add(new MenuItem(CONTINUE_2D, "Continue: "          ,true));
            levelChangeList.Add(new MenuItem(EXIT,        "Exit"                ,true));


            levelChange2DList = new List<MenuItem>();
            levelChange2DList.Add(new MenuItem(SCORE, "Score: ", false));
            levelChange2DList.Add(new MenuItem(CONTINUE_3D, "Continue", true));
            levelChange2DList.Add(new MenuItem(RESTART_LEVEL_2D, "Play again", true));
            levelChange2DList.Add(new MenuItem(EXIT, "Exit", true));

            levelLose2DList = new List<MenuItem>();
            levelLose2DList.Add(new MenuItem(SCORE, "YOU LOSE!!!", false));
            levelLose2DList.Add(new MenuItem(RESTART_LEVEL_2D, "Continue", true));
            levelLose2DList.Add(new MenuItem(EXIT, "Exit", true));

            pauseList2D = new List<MenuItem>();
            pauseList2D.Add(new MenuItem(RESUME_2D, "Resume", true));
            pauseList2D.Add(new MenuItem(CONTROLS_2D, "Controls", true));
            pauseList2D.Add(new MenuItem(EXIT, "Exit", true));

            controlsList2D = new List<MenuItem>();
            controlsList2D.Add(new MenuItem(LEFT, "Rotate: Left,Right, Up, Down", false));
            controlsList2D.Add(new MenuItem(SHOT, "Shot: S", false));            
            controlsList2D.Add(new MenuItem(BACK_2D, "Back", true));
            controlsList2D.Add(new MenuItem(EXIT, "Exit", true));
            

            itemList = menuList;
            
            itemList[0].isSelected = true;
            currentItem = 0;

            active = true;

            keyPressDown = false;
            keyPressUp = false;
            keyPressEnter = false;

            optionSelected = false;
            
            menuScreen = true;//menu esta sendo mostrado
            loadingScreen = false;//loading esta sendo mostrado
            controlScreen = false;//controles esta sendo mostrado

            type = TYPE_MENU_START;
            owner = TYPE_MENU_START;
        }

        public void load(GraphicsDevice graphicsDevice,ContentManager content)
        {
            font = content.Load<SpriteFont>("menufont");
            background = content.Load<Texture2D>("background2");
            
            myBackground1 = new ScrollingBackground();
            Texture2D background1 = content.Load<Texture2D>("back01");
            myBackground1.Load(graphicsDevice, background1);

            myBackground2 = new ScrollingBackground();
            Texture2D background2 = content.Load<Texture2D>("back02");
            myBackground2.Load(graphicsDevice, background2);

            star = content.Load<Texture2D>("img/star");

        }
        public void changeMenu(int type)
        {
            LevelManager lm = LevelManager.getInstance();
            Sound s = Sound.getInstance();
            s.setMenuVolume();
            this.type = type;
            switch(this.type)
            {
                
                case TYPE_DEAD:
                    itemList[currentItem].isSelected = false;

                    itemList = deadList;
                    
                    currentItem = 1;
                    itemList[currentItem].isSelected = true;
                    
                    break;
                case TYPE_PAUSE:
                    itemList[currentItem].isSelected = false;
                    
                    itemList = pauseList;
                    
                    currentItem = 0;
                    itemList[currentItem].isSelected = true;
                    owner = TYPE_PAUSE;
                    
                    break;
                case TYPE_PAUSE_2D:
                    itemList[currentItem].isSelected = false;

                    itemList = pauseList2D;

                    currentItem = 0;
                    itemList[currentItem].isSelected = true;
                    owner = TYPE_PAUSE_2D;

                    break;
                case TYPE_MENU_START:
                    itemList[currentItem].isSelected = false;
                    
                    itemList = menuList;
                    
                    currentItem = 0;
                    itemList[currentItem].isSelected = true;
                    owner = TYPE_MENU_START;
                    break;
                case TYPE_CHANGE_LEVEL_3D:
                    itemList[currentItem].isSelected = false;
                    
                    itemList = levelChangeList;
                    
                    if(lm.nextLevel=="")
                    {
                        LevelManager2D lm2D = LevelManager2D.getInstance();

                        levelChangeList[0].title = "YOU WIN!!";
                        levelChangeList[1].title = "Enemy Kill : " + (int)((100.0f * lm.totalEnemiesKill) / lm.totalEnemies) + " %";
                        levelChangeList[2].title = "Power Ups  : " + (int)((100.0f * lm.totalPowerUpsCatch) / lm.totalPowerUps) + " %";
                        levelChangeList[3].title = "Mini game  : " + (int)((11.0f / lm2D.gui.totalNrShots) * 100) + " %";//11 shots para 9 levels
                        levelChangeList[3].selectable = false;
                        currentItem = 4;
                    }
                    else
                    {
                        //depois de encerrar a fase 3d e passar pelo menu vai para o next level 2d
                        levelChangeList[0].title = "Score: " + lm.score;
                        levelChangeList[1].title = "Enemy Kill: " + lm.nrEnemysKill + " / " + (lm.towerList.Count + lm.shipList.Count);
                        levelChangeList[2].title = "Power Ups: " + lm.nrPowerUpsCatch + " / " + (lm.powerUpList.Count);
                        levelChangeList[3].title = "Continue: "     + lm.nextLevel;
                        currentItem = 3;                        
                    }
                    
                    
                    itemList[currentItem].isSelected = true;
                    
                    break;
                case TYPE_CHANGE_LEVEL_2D:

                    itemList[currentItem].isSelected = false;

                    itemList = levelChange2DList;

                    itemList[0].title = "Score: ";
                    

                    currentItem = 1;
                    
                    itemList[currentItem].isSelected = true;
                    
                    break;
                case TYPE_LOSE_LEVEL_2D:
                    itemList[currentItem].isSelected = false;

                    itemList = levelLose2DList;

                    currentItem = 1;
                    
                    itemList[currentItem].isSelected = true;
                    
                    break;
            }
        }
        public void update(KeyboardState ks,GameTime gameTime)
        {
            optionSelected = false;

            foreach (MenuItem item in itemList)
                item.update(gameTime);

            Sound s = Sound.getInstance();
            if (ks.IsKeyDown(Keys.Down))
                keyPressDown = true;
            else if (ks.IsKeyDown(Keys.Up))
                keyPressUp = true;
            else if (ks.IsKeyDown(Keys.Enter))
                keyPressEnter = true;

            if (keyPressDown && ks.IsKeyUp(Keys.Down))
            {
                itemList[currentItem].isSelected = false;
                currentItem = getNextItemSelectable(currentItem);
                s.soundBank.PlayCue("menu_cancel");
                keyPressDown = false;
            }
            else if (keyPressUp && ks.IsKeyUp(Keys.Up))
            {
                itemList[currentItem].isSelected = false;
                currentItem = getPrevItemSelectable(currentItem);
                s.soundBank.PlayCue("menu_cancel");
                keyPressUp = false;
            }
            else if (keyPressEnter && ks.IsKeyUp(Keys.Enter))
            {
                optionSelected = true;
                keyPressEnter = false;
                s.soundBank.PlayCue("menu_select");
            }
            
            itemList[currentItem].isSelected = true;


            if (optionSelected )
            {
                switch (getAction())
                {
                    case CAMERA:

                        LevelManager lm = LevelManager.getInstance();
                        if(lm.camPos.Y == 1000)
                            lm.camPos.Y = 400;
                        else
                            lm.camPos.Y = 1000;

                        break;
                    case NEWGAME:
                        loadingScreen = true;//vai desenhar o loading e no proximo frame chama o loadGame() no update do game.
                        execAction = true;
                        break;
                    case CONTROLS:
                        controlScreen = true;
                        itemList[currentItem].isSelected = false;
                
                        itemList = controlsList;
                        currentItem = itemList.Count - 2;

                        itemList[currentItem].isSelected = true;
                        
                        break;
                    case BACK:
                        controlScreen = false;
                        menuScreen = true;

                        itemList[currentItem].isSelected = false;                

                        if(owner == TYPE_PAUSE)
                            itemList = pauseList;
                        else
                            itemList = menuList;

                        currentItem = 0;

                        itemList[currentItem].isSelected = true;
                
                        break;
                    case CONTROLS_2D:
                        controlScreen = true;
                        itemList[currentItem].isSelected = false;

                        itemList = controlsList2D;
                        currentItem = itemList.Count - 2;

                        itemList[currentItem].isSelected = true;

                        break;
                    case BACK_2D:
                        controlScreen = false;
                        menuScreen = true;

                        itemList[currentItem].isSelected = false;

                        itemList = pauseList2D;
                        currentItem = 0;

                        itemList[currentItem].isSelected = true;

                        break;
                    case CONTINUE_3D:
                        loadingScreen = true;
                        execAction = true;

                        LevelManager2D lm2D = LevelManager2D.getInstance();
                        lm2D.gui.totalNrShots += 5-lm2D.gui.nrshots;//quantos foram usados

                        break;
                    case CONTINUE_2D:
                        loadingScreen = true;
                        execAction = true;
                        break;
                    case RESUME:
                        s.setGameVolume();
                        execAction = true;
                        break;
                    case RESUME_2D:
                        s.setGameVolume();
                        execAction = true;
                        break;
                    case RESTART_LEVEL_3D:
                    case RESTART_LEVEL_2D:
                        execAction = true;
                        break;
                }
            }
            int velMap = 200;

            myBackground1.Update((float)(gameTime.ElapsedGameTime.TotalSeconds * velMap / 2));
            myBackground2.Update((float)(gameTime.ElapsedGameTime.TotalSeconds * velMap / 3));


        }
        
        private int getNextItemSelectable(int index)
        {
            index++;
            if (index >= itemList.Count)
                index = 0;
            while(!this.itemList[index].selectable)
            {
                index++;
                if(index >= itemList.Count)
                    index = 0;
            }
            return index;
        }
        private int getPrevItemSelectable(int index)
        {
            index--;
            if (index < 0)
                index = itemList.Count - 1;
            while(!this.itemList[index].selectable)
            {
                index--;
                if(index < 0)
                    index = itemList.Count-1;
            }
            return index;
        }
        
        public Boolean exit()
        {
            return (optionSelected && getAction() == Menu.EXIT);
        }
        public int getAction()
        {
            return this.itemList[currentItem].id;
        }
        public int getMenuActive()
        {
            return type;
        }

        public void draw(GameTime gameTime, SpriteBatch spriteBatch, GraphicsDeviceManager graphics)
        {

            
            spriteBatch.Draw(background, new Rectangle(0,0,graphics.GraphicsDevice.Viewport.Width,graphics.GraphicsDevice.Viewport.Height), Color.White);

            if (!loadingScreen)
            {
                myBackground2.Draw(spriteBatch);
                myBackground1.Draw(spriteBatch);
            }

            

            spriteBatch.DrawString(font, "Mia Project", new Vector2(graphics.GraphicsDevice.Viewport.Width / 2 - 75, 20), Color.White);

            
            int i = 0;
            if (loadingScreen)
            {
                spriteBatch.DrawString(font, "Loading...", new Vector2(graphics.GraphicsDevice.Viewport.Width - 150, graphics.GraphicsDevice.Viewport.Height - 50), Color.Yellow);
            }
            else
            {
                float h = graphics.GraphicsDevice.Viewport.Height / 2 - (itemList.Count * 40) / 2;
                foreach (MenuItem item in itemList)
                {
                    Vector2 titlePosition = new Vector2(graphics.GraphicsDevice.Viewport.Width / 2 - 75, h + (i * 40));
                    Vector2 titleOrigin = font.MeasureString(item.title) / 2;

                    Color color = item.isSelected ? Color.Yellow : Color.White;

                    // Pulsate the size of the selected menu entry.
                    double time = gameTime.TotalGameTime.TotalSeconds;

                    float pulsate = (float)Math.Sin(time * 6) + 1;

                    float scale = 1 + pulsate * 0.05f * item.selectionFade;

                    // Modify the alpha to fade text out during transitions.
                    //color *= screen.TransitionAlpha;

                    // Draw text, centered on the middle of each line.

                    Vector2 origin = new Vector2(0, font.LineSpacing / 2);

                    spriteBatch.DrawString(font, item.title, titlePosition, color, 0, origin, scale, SpriteEffects.None, 0);

                    i++;
                }

                if(this.type == TYPE_CHANGE_LEVEL_2D)
                {

                    LevelManager2D lm2D = LevelManager2D.getInstance();
                    int x = 425;
                    int y = 145;

                    for (i = 0; i < lm2D.gui.nrshots; i++)
                    {
                        spriteBatch.Draw(star, new Rectangle(x, y, 32, 32), Color.White);
                        x += 40;
                    }
                } 

                

            }
        }


    }
}
